#pragma once
#include "oratypes.h"
#include <stdlib.h>
#include "oci.h"
#include "DBTOOLS.h"
#include <vector>

struct ColumnInfo
	{
		ub4 Position;		//column position in columns
		ub4 ColumnID;		//column array subscript or IOV column array subscript
		CString ColumnName;	//column name
		ub4 DataType;		//data type
		ub4 MaxSize;		//max data size in bytes(this may not available)
		bool bIsIOVCol;		//indicate if this column is IOV column
	};

class FMDBColumn
{
public:
	FMDBColumn(void);
	FMDBColumn(int ColumnId,int Size,ub2 OraType);
	~FMDBColumn(void);

	void SetColumnId(int val){m_ColId=val;}
	int GetColumnId(){return m_ColId;}

	ColumnInfo GetColumnInfo(){return m_colInfo;}
	void SetColumnInfo(ColumnInfo val){m_colInfo=val;}

	//set storage size.size is element quantity.
	void SetStorageBySize(int Size)
	{
		if (m_Storage)
		{
			free(m_Storage);
		}
		//note:here we needn't use memset, because the oracle API will full fill this memory block.
		m_Storage=malloc(m_colInfo.MaxSize*Size);

		if(m_pInd)
		{
			free(m_pInd);
		}
		m_pInd=(sb2*)malloc(sizeof(sb2)*Size);
	}

	//set storage by byte.size is byte quantity
	//note: this is useful for char*
	/*void SetStorageByByte(int Size)
	{
		if (m_Storage)
		{
			free(m_Storage);
		}
		m_Storage=malloc(Size);
	}*/


	void *GetStorage(){return m_Storage;}
	sb2 *GetIndicator(){return m_pInd;}

	void SetType(ub2 val){m_OraType=val;}
	ub2 GetType(){return m_OraType;}

private:
	int m_ColId;	//column position in a record 1-base;0 means global RowID
	void *m_Storage;//storage
	sb2 *m_pInd;	//indicator of this column
	ub2 m_OraType;	//storage oracle type
	ColumnInfo m_colInfo;
};

class FMDBIOVColumn
{
public:
	FMDBIOVColumn(void);
	FMDBIOVColumn(int ColumnId,int ArraySize,int DataSize,ub2 OraType);
	~FMDBIOVColumn(void);

	void SetColumnId(int val){m_ColId=val;}
	int GetColumnId(){return m_ColId;}

	ColumnInfo GetColumnInfo(){return m_colInfo;}
	void SetColumnInfo(ColumnInfo val){m_colInfo=val;}
	
	void SetStorage(int ArraySize,int DataSize);
	void ResetStorage();
	void RemoveStorage();

	OCIIOV *GetStorage(){return m_OCIIOV;}

	void SetType(ub2 val){m_OraType=val;}
	ub2 GetType(){return m_OraType;}

	int GetDataSize() const { return m_DataSize; }
	void SetDataSize(int val) { m_DataSize = val; }

	sb2 *GetIndicator(){return m_pInd;}
private:
	int m_ColId;		//column position in a record 1-base;0 means global RowID
	OCIIOV *m_OCIIOV;	//storage
	sb2 *m_pInd;		//indicator of this column
	int m_ArraySize;	//OCIIOV elements number
	int m_DataSize;		//data size inside each OCIIOV object
	ub2 m_OraType;		//storage oracle type
	ColumnInfo m_colInfo;
};